import 'package:json_annotation/json_annotation.dart';

import '../socket/dto/base/Req.dart';
import '../socket/dto/business/PullData.dart';
import '../socket/dto/business/WebRtcData.dart';
import '../util/DateUtil.dart';

part 'dto.g.dart';

class WebRtcLoginReq extends TenantReq {
  String authToken;
  String userId;

  WebRtcLoginReq({ required this.userId, required this.authToken, required super.tenantCode,
    required super.terminalType});

  factory WebRtcLoginReq.fromJson(Map<String, dynamic> json) => _$WebRtcLoginReqFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcLoginReqToJson(this);
}

class WebRtcRoomReq extends Req {
  String? roomName;
  String? userId;

  WebRtcRoomReq({ this.roomName, this.userId});
}

class WebRtcCreateRoomReq extends WebRtcRoomReq {

  ChatType chatType;
  TerminalType terminalType;
  String? machineInfo;
  double width;
  double height;

  WebRtcCreateRoomReq({ required this.terminalType, required this.width, required this.height, super.roomName,
    super.userId, required this.chatType, this.machineInfo});

  factory WebRtcCreateRoomReq.fromJson(Map<String, dynamic> json) => _$WebRtcCreateRoomReqFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcCreateRoomReqToJson(this);
}

class WebRtcJoinRoomReq extends WebRtcRoomReq {
  TerminalType terminalType;
  String? machineInfo;
  double width;
  double height;

  WebRtcJoinRoomReq({ required this.terminalType, required this.width, required this.height, required super.roomName,
    this.machineInfo, super.userId});

  factory WebRtcJoinRoomReq.fromJson(Map<String, dynamic> json) => _$WebRtcJoinRoomReqFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcJoinRoomReqToJson(this);
}

class WebRtcExitRoomReq extends WebRtcRoomReq {

  WebRtcExitRoomReq({ required super.roomName, super.userId});

  factory WebRtcExitRoomReq.fromJson(Map<String, dynamic> json) => _$WebRtcExitRoomReqFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcExitRoomReqToJson(this);
}

class WebRtcP2pCandidateReq extends WebRtcRoomReq {

  String toUserId;
  IceCandidate iceCandidate;

  WebRtcP2pCandidateReq({ required super.roomName, super.userId, required this.toUserId,
    required this.iceCandidate});

  factory WebRtcP2pCandidateReq.fromJson(Map<String, dynamic> json) => _$WebRtcP2pCandidateReqFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcP2pCandidateReqToJson(this);
}

class WebRtcP2pSdpReq extends WebRtcRoomReq {

  String toUserId;
  String sdp;
  SdpType sdpType;

  WebRtcP2pSdpReq({ required this.toUserId, required this.sdp, required this.sdpType, required super.roomName, super.userId});

  factory WebRtcP2pSdpReq.fromJson(Map<String, dynamic> json) => _$WebRtcP2pSdpReqFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcP2pSdpReqToJson(this);
}

class WebRtcDelRoomReq extends WebRtcRoomReq {

  WebRtcDelRoomReq({ required super.roomName, super.userId});

  factory WebRtcDelRoomReq.fromJson(Map<String, dynamic> json) => _$WebRtcDelRoomReqFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcDelRoomReqToJson(this);
}

class WebRtcRoomInfo {
  String name;
  String ownerUserId;
  List<WebRtcUserInfo> userInfoList;

  WebRtcRoomInfo({ required this.name, required this.ownerUserId, required this.userInfoList});

  factory WebRtcRoomInfo.fromJson(Map<String, dynamic> json) => _$WebRtcRoomInfoFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcRoomInfoToJson(this);
}

class WebRtcUserInfo {
  String userId;
  TerminalType terminalType;
  String? machineInfo;
  double width;
  double height;

  WebRtcUserInfo({ required this.userId, required this.terminalType, this.machineInfo, required this.width,
    required this.height});

  factory WebRtcUserInfo.fromJson(Map<String, dynamic> json) => _$WebRtcUserInfoFromJson(json);

  Map<String, dynamic> toJson() => _$WebRtcUserInfoToJson(this);
}

class IceCandidate {

  String sdpMid;
  int sdpMLineIndex;
  String candidate;
  String? serverUrl;

  IceCandidate({ required this.sdpMid, required this.sdpMLineIndex, required this.candidate});
}

enum SdpType {
  offer,
  answer;

  static SdpType ofName(String value) {
    return SdpType.values.firstWhere((element) => element.name == value);
  }
}
